﻿/*******************************************************************************
* file  : des demo
* creat : apleilx
* data  : 2017/03/02
*******************************************************************************/
#include "common.h"
#include "str_ext.h"

#define DISP_MODE_HEX			0	// 16进制显示
#define DISP_MODE_IDEC			1	// 10进制显示-有符号
#define DISP_MODE_UDEC			2	// 10进制显示-无符号
#define DISP_MODE_BIN			3	// 2进制显示

/*******************************************************************************
* @brief  8位格式显示内存信息
* \param[in] head :添加信息头
* \retval: data mode
*******************************************************************************/
char mem_head_disp(const void * head)
{
	char mode = DISP_MODE_HEX;

	// 输出头
	if (head)
	{
		ii8 head_site;
		const char *hd = head;

		// 模式选择
		if (hd[0] == 'I' 
			&& hd[1] == ':')
		{
			mode = DISP_MODE_IDEC;
			head_site = 1;
		}
		else if (hd[0] == 'U' 
				 && hd[1] == ':')
		{
			mode = DISP_MODE_UDEC;
			head_site = 1;
		}
		else if (   hd[0] == 'B' 
				 && hd[1] == ':')
		{
			mode = DISP_MODE_BIN;
			head_site = 1;
		}
		else
		{
			head_site = 0;
		}

		// 纯文本判定
		if (head_site > 0)
		{
			head_site++;
			if (!hd[head_site])
			{
				head_site = -1;
			}
		}

		// 打印头
		if (head_site >= 0)
		{
			dbg_print("%s", hd + head_site);
		}
	}

	return mode;
}

/*******************************************************************************
* @brief  8位格式显示内存信息
* \param[in] head :添加信息头
* \param[in] dat  :数据地址
* \param[in] head :长度
* \param[in] line :每行最大显示数量
* \retval: none
*******************************************************************************/
void mem_u8_disp(const void * head, const void * dat, int len, int line)
{
	const uu8 *ch = dat;
	const ii8 *ich = dat;
	char mode;
	int cnt = 0;
	ii8 bit;

	mode = mem_head_disp(head);

	// 输出数据
	while (len--)
	{
		switch (mode)
		{
			case DISP_MODE_UDEC:
				dbg_print("%03d ", *ch++);
				break;
			case DISP_MODE_IDEC:
				dbg_print("%04d ", *ich++);
				break;
			case DISP_MODE_BIN:
				for(bit=7; bit>= 0;bit--)
				{
					if(*ch & (1U << bit))
						dbg_puts("1");
					else
						dbg_puts("0");
				}
				dbg_puts(" ");
				ch++;
				break;
			default:
				dbg_print("%02x ", *ch++);
				break;
		}

		cnt++;

		if ((cnt % line) == 0)
		{
			dbg_print(" =>line#%d\n", cnt / line);
		}
	}

	// 行尾添加换行符
	if ((cnt % line) != 0)
	{
		dbg_puts("\n");
	}
}

/*******************************************************************************
* @brief  16位格式显示内存信息
* \param[in] head :添加信息头
* \param[in] dat  :数据地址
* \param[in] head :长度
* \param[in] line :每行最大显示数量
* \retval: none
*******************************************************************************/
void mem_u16_disp(const void * head, const void * dat, int len, int line)
{
	const uu16 *ch = dat;
	const ii16 *ich = dat;
	char mode;
	int cnt = 0;

	mode = mem_head_disp(head);

	// 输出数据
	while (len--)
	{
		switch (mode)
		{
			case DISP_MODE_UDEC:
				dbg_print("%5d ", *ch++);
				break;
			case DISP_MODE_IDEC:
				dbg_print("%6d ", *ich++);
				break;
			default:
				dbg_print("%04x ", *ch++);
				break;
		}

		cnt++;

		if ((cnt % line) == 0)
		{
			dbg_print(" =>line#%d\n", cnt / line);
		}
	}

	// 行尾添加换行符
	if ((cnt % line) != 0)
	{
		dbg_puts("\n");
	}
}

/*******************************************************************************
* @brief  32位格式显示内存信息
* \param[in] head :添加信息头
* \param[in] dat  :数据地址
* \param[in] head :长度
* \param[in] line :每行最大显示数量
* \retval: none
*******************************************************************************/
void mem_u32_disp(const void * head, const void * dat, int len, int line)
{
	const uu32 *ch = dat;
	const ii32 *ich = dat;
	char mode;
	int cnt = 0;

	mode = mem_head_disp(head);

	// 输出数据
	while (len--)
	{
		switch (mode)
		{
			case DISP_MODE_UDEC:
				dbg_print("%010d ", *ch++);
				break;
			case DISP_MODE_IDEC:
				dbg_print("%011d ", *ich++);
				break;
			default:
				dbg_print("%08x ", *ch++);
				break;
		}

		cnt++;

		if ((cnt % line) == 0)
		{
			dbg_print(" =>line#%d\n", cnt / line);
		}
	}

	// 行尾添加换行符
	if ((cnt % line) != 0)
	{
		dbg_puts("\n");
	}
}